/*
 * twi_master.c
 *
 *      Author: Christian
 *      Letztes Update: 03.11.13 Christian | Code Aufräumen
 *
 */

#include "twi_master.h"
#include <util/twi.h>

/* TWI stop Methode
 * Kein Return wert. Beendet TWI
 */
void twi_stop( void ) {

	TWCR = ( 1 << TWINT ) | ( 1 << TWEN ) | ( 1 << TWSTO );
	while((TWCR & (1<<TWSTO)));
}

/* TWI Initialisierung
 * Frequenz anpassen
 */
void twi_init( void ) {
	PORTC |= ( 1 << PC0 ) | ( 1 << PC1 );


	TWSR = 0;
	TWBR = (( CPU / F_I2C ) - 16) / 2;

}

/* TWI  Adresse senden
 * ausgelagerte Funktion fuer die twi_start Funktion
 *
 * Adresse definieren
 *
 * return 1 bei Erfolg
 */
static uint8_t twi_send_adr( uint8_t adresse ) {

	TWDR = adresse;
	TWCR = ( 1 << TWINT ) | ( 1 << TWEN );

	while ( !( TWCR & ( 1 << TWINT ) ) );

	if ( ( TWSR & 0xF8 ) == !( TW_MT_SLA_ACK ) && !( TW_MR_SLA_ACK ) ) {
		return 0;
	}
	return 1;
}

/* TWI start senden
 *
 * return 1 bei Erfolg
 */
uint8_t twi_start( uint8_t adresse ) {

	TWCR = ( 1 << TWINT ) | ( 1 << TWSTA ) | ( 1 << TWEN );
	while ( !( TWCR & ( 1 << TWINT ) ) );

	if ( ( TWSR & 0xF8 ) != TW_START ) {
		return 0;
	}

	return twi_send_adr ( adresse );

}

/* TWI repstart senden
 *
 * return 1 bei erfolg
 */
uint8_t twi_repstart( uint8_t adresse ) {

	TWCR = ( 1 << TWINT ) | ( 1 << TWSTA ) | ( 1 << TWEN );
	while ( !( TWCR & ( 1 << TWINT ) ) );

	if ( ( TWSR & 0xF8 ) != TW_REP_START ) {
		return 0;
	}

	return twi_send_adr ( adresse );
}

/* Datenbyte senden
 * Adresse muss erfolgreich gesendet worden sein
 *
 * return 1 bei Erfolg
 */
uint8_t twi_send_data( uint8_t data ) {

	TWDR = data;
	TWCR = ( 1 << TWINT ) | ( 1 << TWEN );

	while ( !( TWCR & ( 1 << TWINT ) ) );

	if ((TWSR & 0xF8) != TW_MT_DATA_ACK ){
		return 0;
	}
	return 1;
}


/*TWI Datenbyte empfangen
 * Start Impuls und Adresse muessen gesendet sein
 * nach Empfang kommt stop impuls
 *
 */
uint8_t twi_recieve_data_nack( void ) {

	TWCR = ( 1 << TWINT ) | ( 1 << TWEN );
	while ( !( TWCR & ( 1 << TWINT ) ) );

	return TWDR;

}

/*TWI Datenbyte empfangen
 * Start Impuls und Adresse muessen gesendet sein
 * nach Empfang kommt  KEIN stop impuls
 * */
uint8_t twi_recieve_data_ack( void ) {

	TWCR = ( 1 << TWINT ) | ( 1 << TWEN ) | ( 1 << TWEA );
	while ( !( TWCR & ( 1 << TWINT ) ) );

	return TWDR;

}
